<template>
  <div style="width: 100vw; height: 100vh" class="bg-[#91b1ae]">
    <div id="wrapper" style="width: 100%; height: 100%"></div>
    <!-- <video ref="videoRef" autoplay controls playsinline class="w-full h-full"></video> -->
  </div>
  <!-- 渐变蒙层 -->
  <div
    class="fixed bottom-0 left-0 w-full h-50 bg-black/50 z-1"
    style="background: linear-gradient(to top, #4fb5e9, #83d9eb 160px, transparent)"
  >
    <!-- 问答列表 -->
    <div class="pos-relative">
      <div
        v-show="isChatList"
        ref="scrollContainer"
        style="background: linear-gradient(to top, #7ed6eb, #83d9eb 130px, transparent)"
        class="pos-absolute h-40 top-0 left-0 w-full -translate-y-30 overflow-y-auto mt-4 box-border"
      >
        <div v-for="(msg, index) in chatList" :key="index" mx-6 my-4 :class="msg.type">
          <div :class="[msg.type === 'ai' ? 'text-left text-[#2c5a6e]' : 'text-right text-white']">
            {{ msg.content }}
          </div>
        </div>
      </div>
      <div ref="bottomElement"></div>
    </div>
  </div>
  <!-- 监听输入框 -->
  <div class="fixed flex items-center bottom-10 left-1/2 -translate-x-1/2 z-10">
    <!-- 如果关闭 按钮置灰 -->
    <button class="w-14 h-14 rounded-full" :class="isRecord ? 'bg-white' : 'bg-gray/80'">
      <span
        class="text-2xl text-[#27d3c6]"
        :class="isRecord ? 'i-fluent:mic-24-filled' : 'i-fluent:mic-off-24-filled text-white'"
        @click="changeRecord"
      />
    </button>
    <!-- 音量展示 -->
    <view class="h-12 flex items-center gap-1 mx-2">
      <view
        v-for="(bar, index) in volumeBars"
        :key="index"
        class="w-1 rounded-full transition-all duration-300"
        :class="bar.active ? 'bg-white' : 'bg-white/30'"
        :style="{ height: bar.height }"
      />
    </view>
    <!-- 开关对话列表 -->
    <button class="w-14 h-14 rounded-full" :class="isChatList ? 'bg-white' : 'bg-gray/80'">
      <span
        class="text-2xl text-[#27d3c6]"
        :class="
          isChatList ? 'i-fluent:text-t-20-filled' : 'i-fluent:text-add-t-20-filled text-white'
        "
        @click="handleIsChatList"
      />
    </button>
  </div>
  <!-- 蒙层loading -->
  <div
    class="fixed inset-0 bg-black/60 z-20 flex flex-col justify-center items-center text-white"
    v-if="isLoading"
  >
    <LottieAnimation :jsonData="loadingData" width="200px" height="200px" ref="lottieRef" />
    <div class="text-lg mt-4 max-w-60 text-center">
      我是AI 智游管家小助理，准备好与我互动了吗...
    </div>
    <!-- <button class="mt-4 bg-white text-black px-4 py-2 rounded-md" @click="handleAuthConfirm">
      开始对话
    </button> -->
  </div>
</template>

<script setup lang="ts">
// https://www.yuque.com/xnrpt/bbc1du/xamwb751mbpgeg2o
import loadingData from '@/assets/loading.json'
import AvatarPlatform, { PlayerEvents, SDKEvents } from './vm-sdk/avatar-sdk-web_3.1.1.1011'
// import { useWebRTC } from '@/hooks/useWebRTC'
// 使用WebRTC hook，初始不自动播放
// 使用WebRTC hook
// const { _videoRef, status, isConnected, isPlaying, connect, disconnect } = useWebRTC({
//   autoPlay: false,
//   auth: {
//   appid: '891bcf9e',
//         apikey: 'cf5cb7c494bd02318667daa85220448d',
//         apisecret: 'MDdhZTczYTk4YTkwZjA5NTZiMGIzNjcz',
//         sceneid: '191011410359226368',
// },
// })
// 流地址输入
// const streamUrl = ref('')
// 开始播放流
// const startStream = () => {
//   if (streamUrl.value) {
//     connect(streamUrl.value)
//   } else {
//     alert('请输入WebRTC流地址')
//   }
// }
// 配置信息
const form = reactive({
  appid: '891bcf9e',
  apikey: 'cf5cb7c494bd02318667daa85220448d',
  apisecret: 'MDdhZTczYTk4YTkwZjA5NTZiMGIzNjcz',
  sceneid: '191011410359226368',
  serverurl: 'wss://avatar.cn-huadong-1.xf-yun.com/v1/interact',
})

// 全局参数
const setglobalparamsform = reactive({
  stream: {
    protocol: 'webrtc', //（必传）实时视频协议，支持webrtc/xrtc/rtmp，其中只有xrtc支持透明背景，需参数alpha传1
    fps: 25, //（非必传）视频刷新率,值越大，越流畅，取值范围0-25，默认25即可
    bitrate: 1000000, //（非必传）视频码率，值越大，越清晰，对网络要求越高，默认1000000即可
    alpha: false, //（非必传）是否开启透明背景，0关闭1开始，需配合protocol=xrtc使用
  },
  avatar: {
    avatar_id: '110117005',
    width: 720,
    height: 1920,
    // mask_region: '[0,0,720,1920]',
    scale: 1,
    move_h: 0,
    move_v: 0,
    audio_format: 1,
  },
  tts: {
    vcn: 'x4_lingxiaoying_assist',
    speed: 50,
    pitch: 50,
    volume: 100,
    emotion: 13,
  },
  avatar_dispatch: {
    interactive_mode: 1,
  },
  subtitle: {
    subtitle: 0,
    font_color: '#FFFFFF',
    font_name: 'Sanji.Suxian.Simple',
    position_x: 100,
    position_y: 0,
    font_size: 10,
    width: 100,
    height: 100,
  },
  enable: true,
  background: {
    type: 'res_key',
    data: '22SLM2teIw+aqR6Xsm2JbH6Ng310kDam2NiCY/RQ9n6s3nYJXloZWW1l64/g32vrn7d2lJQR7m9xD5EHYkVs1w82OsRHMfBJqTeSNeD3h+rUX8d0kzGTwW+/WCBOeAbJWqC9oRN7bjXTpOYKG4S339Xq+7mkaJEAIP5tjVq48ns5NS1RDhK30NmC/ZGJYoSXjoilb/BEnJriONLQ2LZ3JnfK9gngbCKgVWrBw17BsvE79IjTI1gyjiZEM65Jxl95CRIhVfa/G0V3+OJUq2S54d+awX9bR72AazfHMt6FIqXKcrNFErG5FPN/Nv9E5Hh585gj3ASzv7LXXgH+aFPu82v7FMN14Hm6Belk0vtLIHQ=',
  },
})

// 实例变量
let avatarPlatform2: any = null
let recorder: any = null
// 开启或者关闭录音按钮
const isRecord = ref(false)
const volume = ref(0)
const isChatList = ref(true)
const isLoading = ref(false)
// 是否由录音权限
const isRecordPermission = ref(false)
// 添加对话列表相关的状态
const scrollContainer = ref<HTMLElement | null>(null)
const bottomElement = ref<HTMLElement | null>(null)
const chatList = ref<
  {
    type: 'user' | 'ai'
    content: string
    request_id: string
  }[]
>([])

// 添加一个标志来记录是否已经初始化
const isInitialized = ref(false)

// 添加消息到对话列表
const addMessage = (content: string, type: 'user' | 'ai', request_id: string) => {
  if (type === 'ai') {
    // 获取同请求id的 ai 消息
    const aiMessage = chatList.value.find(
      (msg) => msg.type === 'ai' && msg.request_id === request_id,
    )
    if (aiMessage) {
      aiMessage.content = content
    } else {
      chatList.value.push({
        type,
        content,
        request_id,
      })
    }
  } else {
    // 用户消息直接添加，不需要检查request_id
    chatList.value.push({
      type,
      content,
      request_id,
    })
  }
}

const handleIsChatList = () => {
  isChatList.value = !isChatList.value
  if (isChatList.value) {
    scrollToBottom()
  }
}

const initWindowSize = () => {
  const { width, height } = useWindowSize()
  // 720/x=width/height
  // 计算resHeight 一定要是四的倍数
  let resHeight = (720 * height.value) / width.value
  // 确保resHeight是4的倍数
  resHeight = Math.floor(resHeight / 4) * 4

  setglobalparamsform.avatar.height = resHeight
  // setglobalparamsform.avatar.mask_region = `[0,0,720,${resHeight}]`
}
// 方法
const initSDK = () => {
  initWindowSize()
  avatarPlatform2 = new AvatarPlatform()
  if (avatarPlatform2 != null) {
    open2('实例化SDK成功')
    createRecoder()
  }
}

const createRecoder = () => {
  if (avatarPlatform2 != null) {
    recorder = avatarPlatform2.createRecorder({
      analyser: true,
    })

    recorder.on('recoder_audio', () => {
      if (recorder && recorder.byteTimeDomainData) {
        const data = recorder.byteTimeDomainData
        let sum = 0
        for (let i = 0; i < data.length; i++) {
          sum += Math.abs(data[i] - 128)
        }
        // 计算音量
        const _volume = sum / data.length
        volume.value = _volume
      }
    })

    open2('创建录音器成功')

    setSDKEvenet()
  } else {
    alert('请实例化SDK实例')
  }
}
const changeRecord = () => {
  if (isRecord.value) {
    stopRecord()
  } else {
    startRecord()
  }
}
const startRecord = () => {
  if (avatarPlatform2 != null) {
    isRecord.value = true
    avatarPlatform2.recorder.startRecord(
      0,
      () => {
        open2('STOPED RECORDER')
      },
      {
        nlp: true,
        avatar_dispatch: {
          interactive_mode: 0,
        },
      },
    )
  } else {
    alert('请先实例化SDK')
  }
}
const setSDKEvenet = () => {
  if (avatarPlatform2 != null) {
    avatarPlatform2
      .on(SDKEvents.connected, (initResp: any) => {
        // streamUrl.value = initResp.stream_url
        // startStream()
        open2('SDKEvent.connect:initResp:', initResp)
      })
      .on(SDKEvents.stream_start, () => {
        open2('stream_start')
      })
      .on(SDKEvents.disconnected, (err: any) => {
        open2('SDKEvent.disconnected:', err)
        if (err) {
          console.error('ws link disconnected because of Error')
          console.error(err.code, err.message, err.name, err.stack)
        }
      })
      .on(SDKEvents.nlp, (nlpData: any) => {
        open2('语义理解内容nlp:', nlpData)
        addMessage(nlpData.content, 'ai', nlpData.request_id)
        scrollToBottom()
      })
      .on(SDKEvents.frame_start, (frame_start: any) => {
        open2('推流开始（可以看作一段文本开始播报时间点）frame_start:', frame_start)
      })
      .on(SDKEvents.frame_stop, (frame_stop: any) => {
        open2('推流结束（可以看作一段文本结束播报时间点）frame_stop:', frame_stop)
      })
      .on(SDKEvents.error, (error: any) => {
        open2('错误信息error:', error)
      })
      .on(SDKEvents.connected, () => {
        open2('connected')
      })
      .on(SDKEvents.asr, (asrData: any) => {
        addMessage(asrData.text, 'user', asrData.request_id)
      })
      .on(SDKEvents.tts_duration, (ttsData: any) => {
        open2('语音合成用时tts：', ttsData)
      })
      .on(SDKEvents.subtitle_info, (subtitleData: any) => {
        open2('subtitleData：', subtitleData)
      })
      .on(SDKEvents.action_start, (action_start: any) => {
        open2('动作推流开始（可以看作动作开始时间节点）action_start:', action_start)
      })
      .on(SDKEvents.action_stop, (action_stop: any) => {
        open2('动作推流结束（可以看作动作结束时间点）action_stop：', action_stop)
      })
    open2('监听SDK事件成功')
    setPlayerEvenet()
  } else {
    alert('请先实例化SDK')
  }
}

const setPlayerEvenet = () => {
  if (avatarPlatform2 != null) {
    const player = avatarPlatform2.createPlayer()
    player
      .on(PlayerEvents.play, () => {
        open2('paly')
      })
      .on(PlayerEvents.playing, () => {
        open2('playing')
        startRecord()
      })
      .on(PlayerEvents.waiting, () => {
        open2('waiting')
      })
      .on(PlayerEvents.stop, () => {
        open2('stop')
      })
      .on(PlayerEvents.playNotAllowed, () => {
        open2(
          'playNotAllowed：触发了游览器限制自动播放策略，播放前必须与游览器产生交互（例如点击页面或者dom组件），触发该事件后调用avatarPlatform2.player.resume()方法来接触限制',
        )
        player.resume()
      })
    open2('监听播放器事件成功')
    SetApiInfo2()
  } else {
    alert('请先实例化SDK')
  }
}

const SetApiInfo2 = () => {
  if (avatarPlatform2 == null) {
    alert('请先实例化SDK')
  } else {
    open2('设置setApiInfo')
    const params = {
      appId: form.appid,
      apiKey: form.apikey,
      apiSecret: form.apisecret,
      serverUrl: form.serverurl,
      sceneId: form.sceneid,
    }
    open2('初始化SDK信息：', params)
    avatarPlatform2.setApiInfo(params)
    open2('初始化SDK成功')
    SetGlobalParams()
  }
}

const SetGlobalParams = () => {
  if (avatarPlatform2 != null) {
    const params = Object.assign({}, setglobalparamsform) as any
    open2('this.setglobalparamsform.stream.alpha', setglobalparamsform.stream.alpha)
    if (setglobalparamsform.enable == false) {
      delete params.background
      delete params.enable
    }
    open2('this.setglobalparamsform', setglobalparamsform)
    if (setglobalparamsform.stream.alpha == true) {
      open2('设置alpha=1')
      params.stream.alpha = 1
    } else {
      open2('设置alpha=0')
      params.stream.alpha = 0
    }
    open2('设置的全局变量为：', params)
    avatarPlatform2.setGlobalParams(params)
    open2('设置全局变量成功')
    start()
  } else {
    alert('请先实例化SDK')
  }
}

const start = () => {
  if (avatarPlatform2 != null) {
    avatarPlatform2
      .start({ wrapper: document.querySelector('#wrapper') })
      .then(() => {
        isLoading.value = false
      })
      .catch((e: any) => {
        console.error(e.code, e.message, e.name, e.stack)
      })
  } else {
    alert('请先实例化SDK')
  }
}
const stopRecord = () => {
  if (avatarPlatform2 != null) {
    avatarPlatform2.recorder.stopRecord()
    isRecord.value = false
    // 还原 蒙层样式
    volume.value = 0
  } else {
    alert('请先实例化SDK')
  }
}
// 生成音量条
const volumeBars = computed(() => {
  const bars: { height: string; active: boolean }[] = []
  const barCount = 20 // 音量条数量
  const activeCount = Math.ceil(volume.value * barCount)

  for (let i = 0; i < barCount; i++) {
    bars.push({
      height: `${Math.random() * 30 + 20}%`, // 随机高度，20%-50%
      active: i < activeCount,
    })
  }
  return bars
})
const destroy = () => {
  if (avatarPlatform2 != null) {
    avatarPlatform2.stop()
    avatarPlatform2.destroy()
    avatarPlatform2 = null
  }
}

const open2 = (text: string, info?: any) => {
  if (!info) {
    // eslint-disable-next-line no-console
    console.log(text)
  } else {
    // eslint-disable-next-line no-console
    console.log(text, info)
  }
}

// 处理页面点击事件
const handlePageClick = () => {
  if (!isInitialized.value && isRecordPermission.value) {
    isInitialized.value = true
    initSDK()
  }
}

const handleAuthConfirm = async () => {
  try {
    // 请求录音权限，这会触发浏览器的权限弹窗
    // 如果拒绝录音 则 uni.webView.navigateTo() 跳转到设置页面
    await navigator.mediaDevices.getUserMedia({ audio: true })
    isRecordPermission.value = true
  } catch (error) {
    console.error('获取录音权限失败：', error)
    uni.webView.navigateBack()
  }
}
// 滚动到底部方法
const scrollToBottom = async () => {
  await nextTick() // 等待 DOM 更新
  if (scrollContainer.value) {
    scrollContainer.value.scrollTo({
      top: scrollContainer.value.scrollHeight,
      behavior: 'smooth',
    })
  }
}
// 生命周期钩子
onMounted(async () => {
  destroy()
  isLoading.value = true
  // 直接调用 handleAuthConfirm，触发浏览器的权限弹窗
  handleAuthConfirm()
  // 添加页面点击事件监听，使用passive选项
  document.addEventListener('click', handlePageClick)
})

onBeforeUnmount(() => {
  document.removeEventListener('click', handlePageClick)
  destroy()
})
</script>
